Skip to content

Conversation

@SavedByGrace251
Copy link

@SavedByGrace251 SavedByGrace251 commented Oct 24, 2025

Introduces a new Menu widget that allows users to display a customizable menu with items in a popup window.

The menu can be configured with a label, icon, menu items, and various styling options such as blur, alignment, and animations.

It enables users to launch applications or execute commands directly from the bar.

desktop (1) desktop (2)

Introduces a new Menu widget that allows users to display a customizable menu with items in a popup window.

The menu can be configured with a label, icon, menu items, and various styling options such as blur, alignment, and animations.

It enables users to launch applications or execute commands directly from the bar.
Addresses potential errors by checking for None values before
applying shadows and styles to the menu widget. This prevents
crashes when shadow configurations or styles are not defined.

Also, clarifies type hints for menu items and shadow attributes
to improve code readability.
@amnweb
Copy link
Owner

amnweb commented Oct 25, 2025

Thanks for contributing! Since we already have a very similar widget Applications, I don’t think we need another one. But since your idea sounds good to me, maybe instead of creating a new widget, it would be better to extend the existing one with popup window support?

There’s already a defined app list, so we can reuse it for the popup if it’s enabled. However, this is a very old widget, and some parts need to be updated, especially the section where we run apps and also I think we can remove ClickableLabel. When apps are launched, they should be completely detached from YASB, similar to how it works in the taskbar.

def _launch_exe(exe_path: str, arguments: str = "", working_dir: str = None) -> None:
"""Launch an executable with subprocess, with UAC elevation if needed."""
# Validate working directory
if not working_dir or not os.path.exists(working_dir):
working_dir = os.path.dirname(exe_path)
if not os.path.exists(working_dir):
working_dir = None
try:
cmd = [exe_path]
if arguments:
try:
# Use shlex to split arguments, then strip quotes from each arg
parsed_args = shlex.split(arguments, posix=False)
# Remove surrounding quotes if shlex preserved them
cleaned_args = [arg.strip('"') for arg in parsed_args]
cmd.extend(cleaned_args)
except ValueError:
# Fallback to simple split if shlex fails
cmd.extend(arguments.split())
subprocess.Popen(
cmd,
cwd=working_dir,
creationflags=subprocess.DETACHED_PROCESS | subprocess.CREATE_NEW_PROCESS_GROUP,
close_fds=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
except OSError as e:
# Check if elevation is required (WinError 740)
if e.winerror == 740:
import win32api
import win32con
try:
win32api.ShellExecute(0, "runas", exe_path, arguments, working_dir, win32con.SW_SHOWNORMAL)
except Exception as shell_error:
logging.error(f"Failed to launch with elevation: {shell_error}")
raise
else:
raise

@SavedByGrace251
Copy link
Author

Oh I didn't even think about extending the applications widget. I'll take a look at extending it and report back!

@amnweb
Copy link
Owner

amnweb commented Oct 25, 2025

Oh I didn't even think about extending the applications widget. I'll take a look at extending it and report back!

Just make sure you don’t break the current users’ configurations if you decide to work on this widget, many themes still use it.

@SavedByGrace251
Copy link
Author

Totally, my thought is a new optional param use_popup that would then look for a label and put item into a pop-up menu instead of a regular list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants